﻿Type.registerNamespace("BM");

BM.ItemsNavigator = {
    getSelectedId: function(item, xpath) {
        /// <summary>
        /// returns the id of a selected item, which is found using a relative xpath from the given anchor item
        /// </summary>
        /// <param name="item" type="MItem" mayBeNull="false">
        /// the anchor item
        /// </param>
        /// <param name="xpath" type="string" mayBeNull="false">
        /// the xpath
        /// </param>
        /// <returns>
        /// the id of the selected item
        /// </returns>
        return BM.ItemsNavigator.getSelectedIdFromId(item.getId(), xpath);
    },

    getSelectedIdFromId: function(id, xpath) {
        /// <summary>
        /// returns the id of a selected item, which is found using a relative xpath from the given anchor item's id
        /// </summary>
        /// <param name="id" type="string" mayBeNull="false">
        /// the id of the anchor item
        /// </param>
        /// <param name="xpath" type="string" mayBeNull="false">
        /// the xpath
        /// </param>
        /// <returns>
        /// the id of the selected item
        /// <returns>
        /// the id of the selected item
        /// </returns>
        if (!xpath) {
            return id;
        }

        var divider = new BM.XPathDivider(xpath);

        if (divider.denotesSelf()) {
            return BM.ItemsNavigator.getSelectedIdFromId(id, divider.rest);
        }

        if (divider.denotesParent()) {
            var parentId = new Path(id).getParentPath();
            return BM.ItemsNavigator.getSelectedIdFromId(parentId, divider.rest);
        }

        var currentIdPart = divider.getNodeTestName().replace(/\:/gi, '__');
        return BM.ItemsNavigator.getSelectedIdFromId(id + '_' + currentIdPart + "_1", divider.rest);
    },

    selectSingle: function(item, xpath) {
        /// <summary>
        /// returns the selected item, which is found using a relative xpath from the given anchor item
        /// </summary>
        /// <param name="item" type="MItem" mayBeNull="false">
        /// the anchor item
        /// </param>
        /// <param name="xpath" type="string" mayBeNull="false">
        /// the xpath
        /// </param>
        /// <returns>
        /// the selected item
        /// </returns>
        return MItem.getById(BM.ItemsNavigator.getSelectedId(item, xpath));
    }
}

BM.XPathDivider = function(xpath) {
    var slashIndex = xpath.indexOf('/');
    if (slashIndex == -1) {
        this.rest = null;
        this.current = xpath;
    } else {
        this.rest = xpath.substring(slashIndex + 1);
        this.current = xpath.substring(0, slashIndex);
    }
}

BM.XPathDivider.prototype = {
    denotesSelf: function() {
        return (this.current == '.' || this.current == '');
    },

    denotesParent: function() {
        return (this.current == '..');
    },

    getNodeTestName: function() {
        if (this.current.startsWith('@')) {
            return this.current.substring(1);
        }

        return this.current;
    }
}